import { defineComponent, provide, getCurrentInstance, toRef, Ref, InjectionKey, PropType } from 'vue'
import { filterEmpty, getSlot } from '../_util/props-util'
import { useMemo } from '../_util/hooks'
import { mapOptions, WillOption } from '../_util/normalizeOptions'
import Radio from './Radio'

export type RadioGroupContextProps = {
  disabledRef: Ref<boolean>
  nameRef: Ref<string>
  valueRef: Ref<string>
  onChange: (e: string | number) => void
}

export const radioGroupContext: InjectionKey<RadioGroupContextProps> = Symbol('radioGroupContext')

const prefixCls = 'x-radio-group'

export default defineComponent({
  name: prefixCls,
  props: {
    name: String,
    options: Array as PropType<WillOption[]>,
    value: [String, Number],
    vertical: Boolean,
    disabled: Boolean
  },
  emits: ['update:value', 'change'],
  setup(props, { emit }) {
    const { proxy: self } = getCurrentInstance()

    const value = useMemo(() => props.value)

    function onChange(val: string | number) {
      value.value = val
      emit('update:value', val)
      emit('change', val)
    }

    // ========================== Provide ==========================
    provide(radioGroupContext, {
      disabledRef: toRef(props, 'disabled'),
      nameRef: toRef(props, 'name'),
      valueRef: value,
      onChange
    })

    return () => {
      let children
      if (props.options?.length) {
        children = mapOptions(props.options, opt => (
          <Radio key={opt.value} checked={value.value == opt.value} name={props.name} value={opt.value} disabled={opt.disabled || props.disabled} style={opt.style}>
            {opt.label}
          </Radio>
        ))
      } else {
        children = filterEmpty(getSlot(self))
      }

      const cls = [prefixCls, props.vertical && `${prefixCls}-vertical`]

      return <div class={cls}>{children}</div>
    }
  }
})
